﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using OfficeOpenXml;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static DFGK_WMS.IRepository.ITTransferBinOrderDetailRepository;

namespace DFGK_WMS.Repository
{
    public class TMaterialRepository : BaseRepository<TMaterial>, ITMaterialRepository
    {
        private readonly ITShippingLockCellRepository tShippingLockCell;

        public TMaterialRepository(DFGK_DB context, IMapper mapper,ITShippingLockCellRepository tShippingLockCell) : base(context, mapper)
        {
            this.tShippingLockCell = tShippingLockCell;
        }

        /// <summary>
        /// 添加物料
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMaterial(TMaterial m)
        {
            try
            {
                var obj = Context.TMaterials.AsNoTracking().FirstOrDefault(x => x.Code == m.Code);
                if (obj != null)
                {
                    return false;
                }
                m.CreateUserId = m.NowUserId;
                m.CreateUserName = m.NowUserRealName;
                m.ModifyUserId = m.NowUserId;
                m.ModifyUserName = m.NowUserRealName;
                m.CreateDate = DateTime.Now;
                m.ModifyDate = DateTime.Now;
                m.TypeId = 2;
                m.TypeName = "成品";
                m.TypeCode = "EndProduct";
                Context.TMaterials.Add(m);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除物料
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool DelMaterial(int mid)
        {
            var mobj = Context.TMaterials.Find(mid);

            if (mobj != null)
            {
                Context.TMaterials.Remove(mobj);
            }
            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 根据主键获取对象信息
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public TMaterial GetMaterialById(int mid)
        {
            return Context.TMaterials.Find(mid);
        }

        /// <summary>
        /// 生成一个物料号
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public string GetMaterialCode(int mid)
        {
            string mcode = "";
            //查找该分类是否存在
            var obj = Context.TMaterialCategories.Find(mid);
            string mvalue = "";
            if (obj != null)
            {
                mcode += obj.Code + ",";
                //mvalue = obj.Id.ToString();
                int? j = obj.ParentId;
                //无限循环查找该对象是否为父级
                for (int i = 0; ; i++)
                {
                    //不是父级进行查询否则退出循环
                    if (obj.ParentId != 0)
                    {
                        //查找该对象
                        var objs = Context.TMaterialCategories.FirstOrDefault(x => x.Id == j);
                        if (objs != null)
                        {
                            //如果存在拿出编码
                            mcode += objs.Code + ",";
                            j = objs.ParentId;
                        }
                        else
                            break;
                    }
                    else
                        break;
                }

                string result = "";
                for (int i = 1; ; i++)
                {
                    if (i < 10)
                    {
                        result = mvalue + "0000" + i;
                    }
                    else if (i < 100)
                    {
                        result = mvalue + "000" + i;
                    }
                    else if (i < 1000)
                    {
                        result = mvalue + "00" + i;
                    }
                    else if (i < 10000)
                    {
                        result = mvalue + "0" + i;
                    }
                    else
                    {
                        result = i.ToString();
                    }
                    string inputStr = mvalue + "," + mcode + "CQXF";
                    string[] elements = inputStr.Split(",");
                    Array.Reverse(elements);
                    result = string.Join("", elements);
                    var mobj = Context.TMaterials.FirstOrDefault(x => x.Code == result);
                    if (mobj != null)
                    {
                        continue;
                    }
                    else
                        break;
                }

                return result;
            }
            return null;
        }

        /// <summary>
        /// 物料列表显示
        /// </summary>
        /// <param name="mname"></param>
        /// <param name="materialcategoryid"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TMaterial> GetMaterialList(string mname, int materialcategoryid, int pageIndex, int pageSize, out int totalCount)
        {
            var list = Context.TMaterials.AsNoTracking().AsQueryable();

            if (!string.IsNullOrEmpty(mname))
            {
                list = list.Where(x => x.Name.Contains(mname));
            }

            if (materialcategoryid != 0)
            {
                list = list.Where(x => x.MaterialCategoryId == materialcategoryid);
            }

            totalCount = list.Count();

            return list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        }

        /// <summary>
        /// 修改物料
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdMaterial(TMaterial m)
        {
            var list = Context.TMaterials.AsNoTracking().FirstOrDefault(x => x.Id != m.Id && x.Code == m.Code);

            if (list != null)
            {
                return false;
            }

            m.ModifyUserId = m.NowUserId;
            m.ModifyUserName = m.NowUserRealName;
            m.ModifyDate = DateTime.Now;
            Context.TMaterials.Update(m);
            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 导出物料管理
        /// </summary>
        /// <returns></returns>
        public List<TMaterial> GetTMaterialExcel()
        {
            try
            {
                return Context.TMaterials.AsQueryable().ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取全部物料
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TMaterial> GetAllMaterialList()
        {
            try
            {
                return Context.TMaterial.AsQueryable().ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 批量添加物料
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMaterialList(List<TMaterial> list)
        {
            if(list.Count<=0)
            {
                return false;
            }
            Context.TMaterial.AddRange(list);
            return  Context.SaveChanges()>0;
        }
        /// <summary>
        /// 找出有库存的物料
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<MaterialDTO> GetMaterialByInv(string name, int pageIndex, int pageSize, out int totalCount)
        {
            var list = Context.TMaterials.ToList().Where(s=>IsInvHoveMayer(s.Code));
            if (!string.IsNullOrEmpty(name))
            {
                list = list.Where(x => x.Name.Contains(name));
            }
            totalCount = list.Count();
            List<MaterialDTO> listDTO;
            if (list == null)
            {
                return new List<MaterialDTO>();
            }
            listDTO = list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList().Select(s => new MaterialDTO()
            {
                Code = s.Code,
                Name = s.Name,
                ModelSpec = s.ModelSpec,
                UnitName = s.UnitName,
                InvCount = tShippingLockCell.GetInvCount(s.Code),
                KeChuCount = tShippingLockCell.GetKeChuInvCount(s.Code)
            }).ToList();
            return listDTO;
        }
        private bool IsInvHoveMayer(string materCode)
        {
            var invBymaterCode = Context.TInventories.AsNoTracking().Where(s => s.MaterialCode == materCode).ToList();
            if (invBymaterCode != null && invBymaterCode.Count() > 0)
            {
                return true;
            }
            return false;
        }
        public List<TMaterial> ReadExcelData(string filePath)
        {
            //string filePaths = "C:\\excel.xlsx";
            string filePathss = Path.ChangeExtension(filePath, "xls");

            // 使用 EPPlus 打开 Excel 文件
            using (var package = new ExcelPackage(new FileInfo(filePath)))
            {
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
                // 获取 Excel 中的第一个工作表
                ExcelWorksheet worksheet = package.Workbook.Worksheets[0];

                // 获取工作表的总行数和总列数
                int rows = worksheet.Dimension.Rows;
                int columns = worksheet.Dimension.Columns;

                // 创建一个列表来保存从 Excel 中读取的数据
                List<TMaterial> dataList = new List<TMaterial>();

                // 从第二行开始遍历 Excel 表格中的数据
                for (int row = 2; row <= rows; row++)
                {
                    // 读取每一行的数据
                    string value1 = worksheet.Cells[row, 1].Value?.ToString();
                    string value2 = worksheet.Cells[row, 2].Value?.ToString();
                    decimal a = value2.ObjToDecimal();
                    // ...

                    // 将数据添加到列表中
                    //dataList.Add(new TMaterial { Code = value1, TypeId = 1, Tonnagefactor = a, CreateDate = DateTime.Now });
                }
                return dataList;
                // 使用 Entity Framework Core 或 ADO.NET 将数据保存到数据库中
                // ... 这里是将数据保存到数据库的代码
            }

          
        }


        public bool Addlistpliang()
        {
            using (var context = Context.Database.BeginTransaction())
            {
                string a = "C:\\excels.xlsx";

                var excelDataList = ReadExcelData(a);

                Context.TMaterials.AddRange(excelDataList);
                Context.SaveChanges();
                context.Commit();
                return true;
            }

        }

        /// <summary>
        /// 物料下传
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool MaterialDownload(List<TMaterialDto> materialDtos)
        {
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    var result = true;
                    foreach (var m in materialDtos)
                    {
                        //物料组
                        var materialGroup = Context.TMaterialGroups.FirstOrDefault(x=>x.Code == m.MaterialGroup);
                        if(materialGroup == null)
                        {
                            materialGroup = new TMaterialGroup();
                            materialGroup.Code = m.MaterialGroup;
                            materialGroup.Name = m.GroupDesc;
                            materialGroup.Describe = m.GroupDesc;
                            Context.TMaterialGroups.Add(materialGroup);
                            if(Context.SaveChanges() <= 0)
                            {
                                result = false;
                                break;
                            }
                        }

                        //物料类型
                        var materialCategory = Context.TMaterialCategories.FirstOrDefault(x => x.MaterialCategoryCode == m.MaterialType);
                        if(materialCategory == null)
                        {
                            materialCategory = new TMaterialCategory();
                            materialCategory.MaterialCategoryCode = m.MaterialType;
                            materialCategory.Name = m.MaterialType_desc;
                            materialCategory.Remark = m.MaterialType_desc;
                            Context.TMaterialCategories.Add(materialCategory);
                            if(Context.SaveChanges() <= 0)
                            {
                                result = false;
                                break;
                            }
                        }

                        //辅助计量单位
                        //var unitConvertFigre = Context.TUnitConvertFigres.FirstOrDefault(x=>x.uni);

                        //物料
                        var material = Context.TMaterial.FirstOrDefault(x => x.Code == m.MaterialNo);
                        if(material == null)
                        {
                            material = new TMaterial();
                            material.Code = m.MaterialNo;
                            material.Name = m.MaterialDesc;
                            material.TypeId = materialCategory.Id;
                            material.TypeCode = materialCategory.Code;
                            material.TypeName = materialCategory.Name;
                            material.UnitName = m.MaterialUnit;
                            material.MaterialGroupId = materialGroup.Id;
                            material.MaterialGroupCode = materialGroup.Code;
                            material.Length = Convert.ToDecimal(m.Length);
                            material.Height = Convert.ToDecimal(m.Height);
                            material.Width = Convert.ToDecimal(m.Width);
                            material.Unit = m.Unit;
                            material.GrossWeight = Convert.ToDecimal(m.RoughWeight);
                            material.NetWeight = Convert.ToDecimal(m.NetWeight);
                            material.GrossWeightUnitName = m.WeightUnit;
                            material.NetWeightUnitName = m.WeightUnit;
                            material.Volum = Convert.ToDecimal(m.Volume);
                            material.VolumUnitName = m.VolumeUnit;
                            material.CreateDate = Convert.ToDateTime(m.CreateDate);
                            Context.TMaterial.Add(material);
                            if (Context.SaveChanges() <= 0)
                            {
                                result = false;
                                break;
                            }
                        }


                        //物料批次信息
                        var materialKey = new TMaterialKey();
                        materialKey.MaterialId = material.Id;
                        materialKey.MaterialCode = material.Code;
                        materialKey.BatchNo = m.BatchMark;
                        materialKey.ProduceFactory = m.Factory;
                        materialKey.SerialnoParam = m.SerialnoParam;
                        materialKey.TestMark = m.TestMark;
                        materialKey.PurchaseGrp = m.PurchaseGrp;
                        materialKey.GroupName = m.GroupName;
                        materialKey.CreateDate = Convert.ToDateTime(m.CreateDate);
                        Context.TMaterialKeys.Add(materialKey);
                        if (Context.SaveChanges() <= 0)
                        {
                            result = false;
                            break;
                        }
                    }
                    if (!result)
                    {
                        tran.Rollback();
                        return result;
                    }
                    tran.Commit();
                    return result;
                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;  
                }
            }
        }
    }
    
}